﻿using System;
using System.Collections.Generic;
using ActionLogic;
using BehaviorModel.Block;
using log4net;

namespace BehaviorModel
{
    public class BlockController : IBlockController
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(BlockController));

        private static readonly IBlockController _instance = new BlockController();

        private List<IBlock> _blocks;

        private BlockController()
        {
            _blocks = new List<IBlock>();
        }

        public static IBlockController GetInstance()
        {
            return _instance;
        }

        public IBlock this[Guid id]
        {
            get { return _blocks.Find(x => x.Id == id); }
        }

        public void AddBlock(IBlock block)
        {
            logger.Info("ADDING BLOCK: " + block.GetType().Name + " " + block.Id);
            if (block is IExecutable)
            {
                var actionBlock = block as IExecutable;
                actionBlock.OnActionExecuted += (sender) => ActionExecutor.GetInstance().Add(sender);
            }
            _blocks.Add(block);

            StatisticController.GetInstance().Statistic.SubscribeOnUpdating(block);
        }

        public void RemoveBlock(IBlock block)
        {
            //logger.Info("BlockController is Removing Block with id: " + id.ToString());
            //_blocks.Remove(_blocks.Find(x => x.Id == id));
            //StatisticController.GetInstance().Statistic.UnsubscribeOnUpdating(id);
            _blocks.Remove(block);
            StatisticController.GetInstance().Statistic.UnsubscribeOnUpdating(block);
        }

        public void Connect(ISenderBlock senderBlock, IReceiverBlock receiverBlock)
        {
            logger.Info("CONNECT: SENDER " + senderBlock.GetType().Name + " " + senderBlock.Id + " RECEIVER " + receiverBlock.GetType().Name + " " + receiverBlock.Id);
            senderBlock.ConnectReceiverBlock(receiverBlock);
        }

        public void Disconnect(ISenderBlock senderBlock, IReceiverBlock receiverBlock)
        {
            logger.Info("DISCONNECT: SENDER " + senderBlock.GetType() + " RECEIVER " + receiverBlock.GetType());
            senderBlock.DisconnectReceiverBlock(receiverBlock);
        }
        
        public void InitBlocks()
        {
            logger.Info("INITBLOCKS");
            foreach (var block in _blocks)
            {
                block.Initialize();
            }
        }
        
    }
}